数据库
数据库就是存储数据的,那么存储数据就用txt就行了啊,为什么要有数据库?
- 数据库有行、列的概念,数据有关系,数据不是散的。
- 据库能够提供非常方便的接口,让增删改查操作变得简单
- 数据库不能自己玩儿,要给向PHP、.net、jsp等语言提供接口。
老牌数据库,比如MySQL、SQL Server、Oracle、Access。这些数据库,我们管他们叫做结构型数据库。每个表中,都有明确的字段,每行记录,都有这些字段,不能有的行有,有的行没有。
非结构型数据库NoSQL
在大数据时代,如果数据库中存储的数据很多,如果突然需要改变某个字段,很不方便,因为所谓的字段,是表的一个结构,所有的行都必须拥有,不能有的行有这个字段,有的行没有这个字段。
所以非结构型数据库 NoSQL 应运而生,NoSQL 是个怪胎,无法挑战老牌数据库,但是在大数据时代有自己的意义。NoSQL 非结构型数据库,没有行、列的概念,用JSON来存储数据,集合就相当于“表”,文档就相当于“行”。
在 NoSQL 中,最小的“数据条目”,不是“行”,而是“文档”。文档就是键值对的一个集合,实际上表达方式和JSON一样。
文档就是JSON,但是要比JSON多了一些限制:
- 每个文档必须有一个特殊的键 _ID ,这个键在集合中必须是唯一的。
- 文档中的所有键不能重复;大小写不同的键,视为不同的键。
- 文档中键的命名,不能含有.和$,其他不限,甚至可以用中文命名、阿拉伯数字。
- 文档中值的类型,比JavaScript中多了一些,比如日期、ObjectId()、正则表达式。
- 文档给程序员看的时候,是JSON的表示模式,但是实际存储的时候,是BSON方式,即用二级制方式存储。
NoSQL数据库包括四大类:键值存储数据库、列存储数据库、文档型数据库,图像数据库。
NoSQL数据库在以下的这几种情况下比较适用:
- 1、数据模型比较简单;
- 需要灵活性更强的IT系统;
- 对数据库性能要求较高;
- 不需要高度的数据一致性;
- 对于给定key,比较容易映射复杂值的环境。
mysql 与 mongoDB 对比图:
MongoDB
MongoDB 属于NoSQL 文档型数据库,主要命令以三种开头:
- mongo 使用数据库
- mongod 开启
- mongoimport 导入数据
打开命令行 CMD,开启命令为:mongod --dbpath E:\mongo
,其中 –dbpath 就是选择数据库文档所在的文件夹。这个 CMD 不能动了,不能关,不能ctrl+c。 一旦这个cmd有问题了,数据库就自动关闭了。所以,应该再开一个cmd。输入:mongo
如果是3.0以上的 mongdb 则这样开启 mongod --storageEngine mmapv1 --dbpath 数据目录
,3.2 版本开始,MongoDB 支持多数据存储引擎(Storage Engine),MongoDB 支持的存储引擎有:WiredTiger,MMAPv1 和 In-Memory。
那么,运行环境就是mongo语法了,下面是一些经常用的增删改查方法:
- 列出所有数据库:show dbs
- 使用某个数据库:use 数据库名字,use一个不存在的,就是新建
- 查看当前所在数据库:db
- 插入数据:
db.student.insert({"name":"xiaoming","age":"12","sex","male"})
,student就是所谓的集合。集合中存储着很多json。如果student是第一次使用,集合将自动创建。 - 清屏:cls
- 删除数据库,删除当前所在的数据库:db.dropDatabase();
- 将 JSON 导入数据库:
mongoimport --db test --collection restaurants --drop --file primer-dataset.json
:- –db test 想往哪个数据库里面导入
- –collection restaurants 想往哪个集合中导入
- –drop 把集合清空
- –file primer-dataset.json 哪个文件
- 查找数据,用find(),findOne() 则只获取第一条:
- find中没有参数,那么将列出这个集合的所有文档:
db.restaurants.find()
- 精确匹配:
db.student.find({"score.shuxue":70});
- 多个条件:
db.student.find({"score.shuxue":70 , "age":12})
- 大于条件:
db.student.find({"score.yuwen":{$gt:50}})
- 或者,寻找所有年龄是9岁,或者11岁的学生:
db.student.find({$or:[{"age":9},{"age":11}]})
- 查找完毕之后,打点调用sort,表示升降排序:
db.restaurants.find().sort({ "borough": 1, "address.zipcode": 1 })
- find中没有参数,那么将列出这个集合的所有文档:
- 查找名字叫做小明的,把年龄更改为16岁:
db.student.update({"name":"小明"},{$set:{"age":16}})
- 查找数学成绩是70,把年龄更改为33岁:
db.student.update({"score.shuxue":70},{$set:{"age":33}})
- 默认情况下,update() 方法更新单个文档。要更新多个文档,请在update() 方法中使用多重选项 {multi: true}:
db.student.update({"sex":"男"},{$set:{"age":33}},{multi: true});
- 完整替换,不出现$set关键字了:
db.student.update({"name":"小明"},{"name":"大明","age":16});
- 删除数据,默认删除全部匹配项:
db.restaurants.remove({ "borough": "Manhattan" })
,如果需要删除单项,请加{justOne: true} :db.restaurants.remove({ "borough": "Queens" }, { justOne: true })
- 删除子文档数据:
db.collection.update({ field: <query> }, { $pull: { field: <query> }});
例如:db.test.update({"userId":100000077},{"$pull":{"cartList":{"productId":201710009}}})
;
需要说明的是,find() 的第二个参数限制返回的 filed 的个数,0代表不返回,1代表返回:
1 | db.Student.find({name:"jack"},{name:1,age:1}) |
“$lt”,”$lte”,”$gt”,”$gte”分别对应<,<=,>,>= ,此外还有:逻辑操作符:”$or”, “$and”,”$not”,”$nor”,以及包含与不包含:”$in”,”$nin”。
MongoDB 分页
假如我们有有一个学生列表需要分页,那么有两种做法:
- 错误的做法: 就是讲所有的result都读取到数组,然后进行数据操作,进行分页;
- 正确的做法: 就是真的在数据库中,只读取这么多内容。
如果利用第一种错误的方式,我们试图每次都读取全部数据,但是这样开销很大:
1 | var a = []; |
所以,mongodb提供了傻傻的两个函数: limit() 和 skip():
假如第一页是page=0。每页10条,所以当前页的查询语句:
1 | db.student.find({}).limit(10).skip(page*10) |
得到数据总数:
1 | db.student.stats().count |
mongoDB 索引
在数据库操作中,根据一个字段的值,来寻找一个文档,是很常见的操作,比如根据学号来找一个学生。
这个学号,是唯一的,只要有学号,就能唯一确认一个学生的文档(类似于结构型数据库中的主键)。学号这个属性,就非常适合建立索引,这样一来,查找学生就变得简单了。
学生的姓名是唯一的,为了快速的进行检索,所以就把name属性建立成为“索引”:
1 | db.student.createIndex({"name":1}); |
这样,今后通过 name 寻找 student 文档的时候,速度非常快。因为能够快速的从索引表中,找到这个文档。缺点就是插入每条数据的时候,时间变慢了,效率低了。但是换回来的就是寻找的速度快了。
索引这个属性,所有的文档都不能相同:
1 | db.members.createIndex({"user_id": 1}, {unique: true }); |
需要注意的是:前面有说到过,在 mongoDB 中,每条数据都有一个特殊的键 _id ,这个键在集合中是唯一的,只是来实际查找中没有那么方便,使用时需要引入require('mongodb').ObjectID;
,且数值是随机的一串,不是我们自己写入的,比较不好控制。
mongoDB 使用
一个简易的留言板增删改查:
数据库增删改查封装,db.js:
1 | //这个模块里面封装了所有对数据库的常用操作 |
后台代码,backstage.js:
1 | //这个模块是后台的接口代码 |
前端html模板,index.ejs:
1 |
|
通过配置文件的形式启动MongoDB
a.在c:\MongoDB(可随意起)下面建一个data文件夹 c:\MongoDB\data
b.在c:\MongoDB(可随意起)下面建一个logs文件夹 c:\MongoDB\logs ,在里面建一个文件mongo.log
c.在c:\MongoDB(可随意起)下面建一个etc(随意起,放配置文件)文件夹 c:\MongoDB\etc ,在里面建一个文件mongo.conf
d.打开mongo.conf文件,修改如下:
1 | 数据库路径 |
完成以上操作后,我们就可以启动我们的mongo数据库了:
在 cmd 命令行运行:
1 | mongod --config e:\mongomallsystem\etc\mongo.conf |
注意:运行这条命令后,命令行没有任何反应,查看27017的端口也无法查看连接,但是数据库是开启状态的,这时候打开另外一个 cmd 就可以进行数据库操作了。
如果希望查看,也可以开启端口查看:
1 | mongod --config e:\mongomallsystem\etc\mongo.conf --httpinterface |
通过以上命令就完成了,并且可以通过默认28017查看数据库状态日志,以后每次运行数据库执行 mongo.conf 配置文件就行
当然,以上是通过配置的形式,来启动我们的MongoDB,也可以把参数直接在启动的时候,传递进去如下:
1 | mongod --dbpath e:\mongomallsystem\data --logpath e:\mongomallsystem\logs\mongodb.log --journal |
安装到window 服务当中
输入命令:
1 | mongod --config e:\mongomallsystem\etc\mongo.conf --install --serviceName "MongoDB" |
安装成功后,打开window服务(win10在任务管理器上可以看到window服务),我们可以看到里面已经安装了MongoDB。
每天,我们用的时候,只需要启动服务即可,如果大家不安装此服务也可以,每次启动的时候,手动进入到安装目录里面,输入命令启动,两种方式都可以。
删除服务命令:mongod –config c:\MongoDB\etc\mongo.conf –remove 然后在服务里面刷新一下,就会发现已经删掉了。
完~